package web.com.IcsUtile;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.activation.DataHandler;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;

/**
 *@Description
 *@author shine
 *创建时间2022/8/5 14:04
 */
@Component
public class MailOutlook {
    Session session;    //创建session
    static String name = "38519040@QQ.com";				//发送用户邮箱
    static String pwd = "vwavkfctnnvkbhjj";					//发送用户密码
    static String username = "shinewang@aslcn.com.cn"; 		//接收用户邮箱
    static String title = "主题_icsTest";					//发送邮件主题
    static String text = "outlook_功能测试";					//发送邮件内容
    static String startTimew = "2022-08-12 7:25:00";//开始时间
    static String endTimew = "2022-08-12 09:00:00";	//结束时间
    //需要转换的时间
    static String startTime = getUtc(startTimew);
    static String endTime = getUtc(endTimew);
    static final  String UID ="123jkl321oiu111222";

    private static Properties emailProp = new Properties();
    private static class EmailAuthenticator extends Authenticator {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            String userId = emailProp.getProperty("userId", name);
            String password = emailProp.getProperty("password", pwd);
            return new PasswordAuthentication(userId, password);
        }
    }

    public  static void send() throws Exception {
        try {
            String fromEmail = emailProp.getProperty("fromEmail", name);
            String toEmail=emailProp.getProperty("toEmail", username);
            Properties props = new Properties();
            try {
                //端口一般为 25/465/487 可以使用telnet host port查看是否可用 比如 telnet mail.unipower.cn 25
                props.put("mail.smtp.port", "25");
                //配置outlook上查到的host
                props.put("mail.smtp.host", "smtp.qq.com");
                props.put("mail.transport.protocol", "smtp");
                props.put("mail.smtp.auth", "true");
                props.put("mail.smtp.ssl", "true");
            } catch (Exception e) {
                e.printStackTrace();
            }

            Session session;
            Authenticator authenticator = new EmailAuthenticator();
            session = Session.getInstance(props, authenticator);
            MimeMessage message = new MimeMessage(session);
            //设置发件人
            message.setFrom(new InternetAddress(fromEmail));
            //设置单个收件人
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
            /*
             	设置多收件人，Message.RecipientType.CC:密送
             				Message.RecipientType.BCC:抄送
             				Message.RecipientType.TO：收件人
             */
//            List<String> emails = new ArrayList<>();
//            emails.add(username);
//            message.addRecipients(Message.RecipientType.TO,setRecipientT0(emails));
            message.setSubject(title);
            StringBuffer buffer = new StringBuffer();
            buffer.append("BEGIN:VCALENDAR\n"
                    + "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n"
                    + "VERSION:2.0\n"
                    + "METHOD:REQUEST\n"        //METHOD:CANCEL 取消会议  METHOD:REQUEST 创建和更新会议
                    + "BEGIN:VEVENT\n"
                    + "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:"+fromEmail+"\n"
                    + "ORGANIZER:MAILTO:"+fromEmail+"\n"
                    + "DTSTART:"+startTime+"\n"
                    + "DTEND:"+endTime+"\n"
                    + "LOCATION:会议室01\n"
                    //如果id相同的话，outlook会认为是同一个会议请求，所以使用uuid。
//                    + "UID:"+UUID.randomUUID().toString()+"\n"
                    +  "UID:"+UID+"\n"
                    + "CATEGORIES:111111111r\n"
                    + "DESCRIPTION:"+"会议内容"  	// 会议内容换行为\\n
                    + "SUMMARY:2222222222t\n" + "PRIORITY:5\n"
                    + "SEQUENCE:1\n"			//设置优先级 其中cancel>update>create
                    + "CLASS:PUBLIC\n" + "BEGIN:VALARM\n"
                    + "TRIGGER:-PT15M\n" + "ACTION:DISPLAY\n"
                    + "DESCRIPTION:Reminder\n" + "END:VALARM\n"
                    + "END:VEVENT\n" + "END:VCALENDAR");
            Multipart multipart = new MimeMultipart();
            BodyPart messageBodyPart = new MimeBodyPart();
            // 测试下来如果不这么转换的话，会以纯文本的形式发送过去，
            //如果没有text/calendar;method=REQUEST;charset=\"UTF-8\"，outlook会议附件的形式存在，而不是直接打开就是一个会议请求
            messageBodyPart.setDataHandler(new DataHandler(new ByteArrayDataSource(buffer.toString(),
                    "text/calendar;method=REQUEST;charset=\"UTF-8\"")));
            // 添加会议邀请内容
            multipart.addBodyPart(messageBodyPart);
            // 附件功能
            // 创建消息部分
            BodyPart fujianBodyPart = new MimeBodyPart();
            // 添加网络附件
//            for (int i = 0; i < documents.size(); i++) {
//                URL url = new URL(documents.get(i).getUrl());
//                DataHandler dataHandler = new DataHandler(url);
//                MimeBodyPart messageBodyPart3 = new MimeBodyPart();
//                messageBodyPart3.setDataHandler(dataHandler);
//                messageBodyPart3.setFileName(MimeUtility.encodeText(documents.get(i).getName()));
//                multipart.addBodyPart(messageBodyPart3);
//            }
            message.setContent(multipart,"text/html;charset=UTF-8");
            //message.setText("测试");
            Transport.send(message);
        } catch (MessagingException me) {
            me.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /*** 设置收件人/抄送人/密送人地址信息*/
    private static InternetAddress[] setRecipientT0(List<String> recipientT0List) throws MessagingException, UnsupportedEncodingException, UnsupportedEncodingException {
        if (recipientT0List.size() > 0) {
            InternetAddress[] sendTo = new InternetAddress[recipientT0List.size()];
            for (int i = 0; i < recipientT0List.size(); i++) {
                System.out.println("发送到:" + recipientT0List.get(i));
                sendTo[i] = new InternetAddress(recipientT0List.get(i), "", "UTF-8");
            }
            return sendTo;
        }
        return null;
    }

    //转utc时间
    public static String getUtc(String str){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long millionSeconds = 0;
        try {
            millionSeconds = sdf.parse(str).getTime();
        } catch (ParseException e1) {
            e1.printStackTrace();
        }//毫秒
        Date date = new Date(millionSeconds );
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //格式化日期
        String nowTime="";
        nowTime= df.format(date);
        String utcTime = nowTime.replace("-", "").replace(" ", "T").replace(":", "");//转换utc时间
        return utcTime;
    }
    public static  void cancel() throws Exception {
        try {
            String fromEmail = emailProp.getProperty("fromEmail", name);
            String toEmail=emailProp.getProperty("toEmail", username);
            Properties props = new Properties();
            try {
                //端口一般为 25/465/487 可以使用telnet host port查看是否可用 比如 telnet mail.unipower.cn 25
                props.put("mail.smtp.port", "25");
                //配置outlook上查到的host
                props.put("mail.smtp.host", "smtp.qq.com");
                props.put("mail.transport.protocol", "smtp");
                props.put("mail.smtp.auth", "true");
                props.put("mail.smtp.ssl", "true");
            } catch (Exception e) {
                e.printStackTrace();
            }

            Session session;
            Authenticator authenticator = new EmailAuthenticator();
            session = Session.getInstance(props, authenticator);
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(fromEmail));
            //设置单个收件人
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
              /*
             	设置多收件人，Message.RecipientType.CC:密送
             							Message.RecipientType.BCC:抄送
             							Message.RecipientType.TO：收件人
             */
//            List<String> emails = new ArrayList<>();
//            emails.add(username);
//            message.addRecipients(Message.RecipientType.TO,setRecipientT0(emails));
            message.setSubject(title);
            StringBuffer buffer = new StringBuffer();
            buffer.append("BEGIN:VCALENDAR\n"
                    + "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n"
                    + "VERSION:2.0\n"
                    + "METHOD:CANCEL \n"        //METHOD:CANCEL 取消会议  METHOD:REQUEST 创建和更新会议
                    + "BEGIN:VEVENT\n"
                    + "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:"+fromEmail+"\n"
                    + "ORGANIZER:MAILTO:"+fromEmail+"\n"
                    + "DTSTART:"+startTime+"\n"
                    + "DTEND:"+endTime+"\n"
                    + "LOCATION:会议室01\n"
                    //这里的uuid要和会议邀请的uuid一致，实际生产中可以将uuid存到数据库中
                    + "UID:"+UID
                    + "CATEGORIES:111111111r\n"
                    + "DESCRIPTION:"+"取消会议~~~~~"  	// 会议内容换行为\\n
                    + "SUMMARY:2222222222t\n" + "PRIORITY:5\n"
                    + "SEQUENCE:3\n"			//设置优先级 其中cancel>update>create
                    + "CLASS:PUBLIC\n" + "BEGIN:VALARM\n"
                    + "TRIGGER:-PT15M\n" + "ACTION:DISPLAY\n"
                    + "DESCRIPTION:Reminder\n" + "END:VALARM\n"
                    + "END:VEVENT\n" + "END:VCALENDAR");
            BodyPart messageBodyPart = new MimeBodyPart();
            // 测试下来如果不这么转换的话，会以纯文本的形式发送过去，
            //如果没有text/calendar;method=REQUEST;charset=\"UTF-8\"，outlook会议附件的形式存在，而不是直接打开就是一个会议请求
            messageBodyPart.setDataHandler(new DataHandler(new ByteArrayDataSource(buffer.toString(),
                    "text/calendar;method=REQUEST;charset=\"UTF-8\"")));
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(messageBodyPart);
            message.setContent(multipart);
            //message.setText("测试");
            Transport.send(message);
        } catch (MessagingException me) {
            me.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static   void update() throws Exception {
        try {
            String fromEmail = emailProp.getProperty("fromEmail", name);
            String toEmail=emailProp.getProperty("toEmail", username);
            Properties props = new Properties();
            try {
                //端口一般为 25/465/487 可以使用telnet host port查看是否可用 比如 telnet mail.unipower.cn 25
                props.put("mail.smtp.port", "25");
                //配置outlook上查到的host
                props.put("mail.smtp.host", "smtp.qq.com");
                props.put("mail.transport.protocol", "smtp");
                props.put("mail.smtp.auth", "true");
                props.put("mail.smtp.ssl", "true");
            } catch (Exception e) {
                e.printStackTrace();
            }

            Session session;
            Authenticator authenticator = new EmailAuthenticator();
            session = Session.getInstance(props, authenticator);
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(fromEmail));
            //设置单个收件人
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmail));
             /*
             	设置多收件人，Message.RecipientType.CC:密送
             							Message.RecipientType.BCC:抄送
             							Message.RecipientType.TO：收件人
             */
//            List<String> emails = new ArrayList<>();
//            emails.add("xxx@xxx.com");
//            message.addRecipients(Message.RecipientType.TO,setRecipientT0(emails));
            message.setSubject(title);
            StringBuffer buffer = new StringBuffer();
            buffer.append("BEGIN:VCALENDAR\n"
                    + "PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN\n"
                    + "VERSION:2.0\n"
                    + "METHOD:REQUEST\n"        //METHOD:CANCEL 取消会议  METHOD:REQUEST 创建和更新会议
                    + "BEGIN:VEVENT\n"
                    + "ATTENDEE;ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:"+fromEmail+"\n"
                    + "ORGANIZER:MAILTO:"+fromEmail+"\n"
                    + "DTSTART:"+startTime+"\n"
                    + "DTEND:"+endTime+"\n"
                    + "LOCATION:会议室01\n"
                    //这里的uuid要和会议邀请的uuid一致，实际生产中可以将uuid存到数据库中
                    + "UID:"+UID
                    + "CATEGORIES:111111111r\n"
                    + "DESCRIPTION:"+"update"  	// 会议内容换行为\\n
                    + "SUMMARY:2222222222t\n" + "PRIORITY:5\n"
                    + "SEQUENCE:2\n"			//设置优先级 其中cancel>update>create
                    + "CLASS:PUBLIC\n" + "BEGIN:VALARM\n"
                    + "TRIGGER:-PT15M\n" + "ACTION:DISPLAY\n"
                    + "DESCRIPTION:Reminder\n" + "END:VALARM\n"
                    + "END:VEVENT\n" + "END:VCALENDAR");
            BodyPart messageBodyPart = new MimeBodyPart();
            // 测试下来如果不这么转换的话，会以纯文本的形式发送过去，
            //如果没有text/calendar;method=REQUEST;charset=\"UTF-8\"，outlook会议附件的形式存在，而不是直接打开就是一个会议请求
            messageBodyPart.setDataHandler(new DataHandler(new ByteArrayDataSource(buffer.toString(),
                    "text/calendar;method=REQUEST;charset=\"UTF-8\"")));
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(messageBodyPart);
            message.setContent(multipart);
            //message.setText("测试");
            Transport.send(message);
        } catch (MessagingException me) {
            me.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }




    //main函数 测试
    public static void main(String[] args) {
        try {
//            send();
//            cancel();//必须马上答复
            update();
            System.out.println("success");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
